package com.share.hope.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.hope.entity.RecordInfo;
import com.share.hope.entity.UserInfo;
import com.share.hope.entity.result.R;
import com.share.hope.mapper.RecordInfoMapper;
import com.share.hope.service.RecordInfoService;
import com.share.hope.service.UserInfoService;
import com.share.hope.utils.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

import static com.share.hope.constant.RecordInfoConstant.*;


@Service
@Slf4j
@RequiredArgsConstructor
public class RecordInfoServiceImpl extends ServiceImpl<RecordInfoMapper, RecordInfo> implements RecordInfoService {

    private final UserInfoService userInfoService;

    @Override
    public R<String> punchTheClock(Long userId) {
        String today = DateUtil.getToday();
        RecordInfo recordInfo = RecordInfo.builder().userId(userId).punchTime(today).build();
        try {
            this.save(recordInfo);
        } catch (Exception exception) {
            return R.error("打卡失敗或今日已打卡..");
        }
        Double loveCoin = loveCoinOneDay(userId);
        return R.ok("打卡成功..愛心幣+" + loveCoin);
    }

    private Double loveCoinOneDay(Long userId) {
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("id", userId);
        UserInfo userInfo = userInfoService.getOne(wrapper);

        // 每次打卡都会爱心币+1
        Double loveCoin = userInfo.getLoveCoin();
        loveCoin += PUNCH_LOVE_COIN_ONE_DAY;
        // 连续打卡天数+1
        Integer punchStreak = userInfo.getPunchStreak();
        punchStreak += PUNCH_ADD_ONE;
        userInfo.setPunchStreak(punchStreak);

        // 判断最长打卡时间
        if (userInfo.getPunchLongest() < punchStreak) {
            userInfo.setPunchLongest(punchStreak);
        }
        // 判斷是否额外获得爱心币
        if (punchStreak % ADDITIONAL_BASE == 0) {
            loveCoin += PUNCH_LOVE_COIN_ADDITIONAL;
        }
        userInfo.setLoveCoin(loveCoin);

        userInfoService.updateById(userInfo);
        return loveCoin;
    }

    @Override
    public R<List<JSONObject>> getPunchMonth(Long userId, String date) {
        LambdaQueryWrapper<RecordInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RecordInfo::getUserId, userId);
        wrapper.like(RecordInfo::getPunchTime, date);
        List<RecordInfo> list = this.list(wrapper);

        List<JSONObject> punch = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (RecordInfo recordInfo : list) {
                JSONObject json = new JSONObject();
                json.put("attendanceDate", recordInfo.getPunchTime());
                punch.add(json);
            }
        }
        return R.success(punch);
    }

    @Override
    public R<JSONObject> getCount(Long userId) {
        UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getId, userId));
        JSONObject json = new JSONObject();
        // 连续签到
        Integer punchStreak = userInfo.getPunchStreak();
        json.put("punchStreak", punchStreak);
        // 累计签到
        LambdaQueryWrapper<RecordInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RecordInfo::getUserId, userId);
        long punchCount = this.count(wrapper);
        json.put("punchCount", punchCount);
        // 最大连续
        Integer punchLongest = userInfo.getPunchLongest();
        json.put("punchLongest", punchLongest);
        return R.success(json);
    }
}
